//
// Created by Jeffrey Wei on 2022/11/2.
//

import Alamofire
import Moya

class NetworkParsingPlugin: PluginType {
    func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
        var newRequest = request
        newRequest.timeoutInterval = 15
        return newRequest
    }

    func process(_ result: Result<Response, MoyaError>, target: TargetType) -> Result<Response, MoyaError> {
        let result = parsing(result, target: target)
        guard let target = target as? NetworkTargetType else { return result }
        switch result {
        case .success:
            break
        case let .failure(error):
            guard let error = error.asNetworkError else { break }
            target.handleError(error: error)
        }
        return result
    }

    private func parsing(_ result: Result<Response, MoyaError>, target: TargetType) -> Result<Response, MoyaError> {
        // 不使用ApiTargetType则插件无效,直接返回默认结果
        guard let target = target as? NetworkTargetType else { return result }
        switch result {
        case let .success(response):
            // 解析返回结果为json,解析不出抛出parsingJsonError错误
            guard let json = try? response.mapJSON(),
                  let apiResponse = target.responseType.init(json: json)
            else {
                return Result.failure(MoyaError.underlying(NetworkError.parsingJsonError, response))
            }

            // 根据条件判断是否成功
            switch apiResponse.isSuccess {
            case true:
                return Result.success(response)
            case false:
                // 失败则抛出一个apiError错误并传出apiResponse
                return Result.failure(MoyaError.underlying(NetworkError.apiError(response: apiResponse), response))
            }
        case let .failure(error):
            // 请求的失败,先看是否有网,有网抛出服务器错误serviceError,并传入http的Response,可拿到响应码等
            if case .reachable = NetworkReachabilityManager()?.status {
                return Result.failure(MoyaError.underlying(NetworkError.serviceError(response: error.response), error.response))
            }
            // 没网则抛出一个notReachableNetwork错误
            return Result.failure(MoyaError.underlying(NetworkError.notReachableNetwork, error.response))
        }
    }
}
